package cn.zs.supply.common.core.aspect;

import cn.zs.supply.common.constants.PubKeyDef;
import cn.zs.supply.common.core.domain.result.BaseResult;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.MDC;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public abstract class BaseApiLogAspect {


    public Object printLog(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = null;
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        String operContent = "";
        if (method.getAnnotation(ApiOperation.class) != null) {
            operContent = method.getAnnotation(ApiOperation.class).value();
        }
        String methodName = joinPoint.getSignature().getName();
        String reqSource = MDC.get(PubKeyDef.LOG_REQ_SOURCE);
        String reqTarget = MDC.get(PubKeyDef.LOG_REQ_TARGER);
        long startTime = System.currentTimeMillis();
        try {
            List<Object> printArgs = new ArrayList<>();
            if (joinPoint.getArgs() != null) {
                for (Object obj : joinPoint.getArgs()) {
                    if (obj instanceof HttpServletRequest || obj instanceof HttpServletResponse) {
                        continue;
                    }
                    printArgs.add(obj);
                }
            }
            //前置通知
            log.info("[{}->{}]{}-{},参数:{} ", reqSource, reqTarget, operContent, methodName, printArgs);
            //执行目标方法
            result = joinPoint.proceed();
            long costTime = System.currentTimeMillis() - startTime;
            if (result instanceof ModelAndView) {
                log.info("[{}->{}]{}-{},响应:{},耗时:{}ms.", reqTarget, reqSource, operContent, methodName, ((ModelAndView) result).getModel(), costTime);
            }
            if (result instanceof BaseResult) {
                //返回通知
                log.info("[{}->{}]{}-{},响应:{},耗时:{}ms.", reqTarget, reqSource, operContent, methodName, result, costTime);
            }
            return result;
        } catch (Throwable e) {
            long costTime = System.currentTimeMillis() - startTime;
            //异常通知
            log.error(methodName + "执行异常!", e);
            log.info("[{}->{}]{}-{},异常:{},耗时:{}ms.", reqTarget, reqSource, operContent, methodName, e.getMessage(), costTime);
            throw e;
        }
    }

}